package com.ticket.sass.admin.business.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ticket.sass.admin.business.OrderGroupBusiness;
import com.ticket.sass.admin.dto.input.order.TicketRefundInput;
import com.ticket.sass.admin.dto.input.order.group.OrderGroupListInput;
import com.ticket.sass.admin.dto.output.order.OrderDataModel;
import com.ticket.sass.admin.dto.output.order.TicketOutput;
import com.ticket.sass.admin.dto.output.order.group.OrderGroupListOutput;
import com.ticket.sass.admin.manager.OrderCommodityManager;
import com.ticket.sass.admin.manager.OrderGroupManager;
import com.ticket.sass.admin.manager.OrderManager;
import com.ticket.sass.admin.service.impl.OrderGroupPurchaseDetailServiceImpl;
import com.ticket.sass.admin.service.impl.OrderGroupPurchaseServiceImpl;
import com.ticket.sass.admin.service.impl.OrderServiceImpl;
import com.ticket.sass.admin.service.impl.UserServiceImpl;
import com.ticket.sass.common.entity.tenant.*;
import com.ticket.sass.common.entity.tenant.enums.OrderPayStatus;
import com.ticket.sass.common.entity.tenant.enums.OrderPayType;
import com.ticket.sass.common.entity.tenant.enums.OrderTicketStatus;
import com.ticket.sass.common.entity.tenant.enums.OrderType;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2024-08-14 17:30
 */
@Slf4j
@Service
@AllArgsConstructor
public class OrderGroupBusinessImpl implements OrderGroupBusiness {
    final OrderManager orderManager;
    final UserServiceImpl userService;
    final OrderServiceImpl orderService;
    final OrderGroupPurchaseServiceImpl service;
    final OrderGroupManager orderGroupManager;
    final OrderCommodityManager orderCommodityManager;
    final OrderGroupPurchaseDetailServiceImpl detailService;
    
    
   
    @Override
    public OrderDataModel<OrderGroupListOutput> list(OrderGroupListInput input) {
        List<Long> selectUserIds = userService.getUserIdByCellphone(input.getCellphone());
        if (StrUtil.isNotEmpty(input.getCellphone()) && selectUserIds.isEmpty()) {
            return new OrderDataModel<>();
        }
        input.setUserIds(selectUserIds);
        
        IPage<OrderGroupPurchaseEntity> page = service.iPage(input);
        
        List<OrderGroupListOutput> outputs = page.getRecords().stream().map(OrderGroupListOutput::new).collect(Collectors.toList());
        // 获取订单ID列表
        List<Long> ids = outputs.stream()
            .map(OrderGroupListOutput::getId)
            .collect(Collectors.toList());
        
        Map<Long, List<TicketOutput>> ticketDetailsByOrderTicketIds = detailService.getTicketDetailsByOrderTicketIds(ids);
        
        // 提取用户ID列表
        List<Long> userIds = outputs.stream()
            .map(OrderGroupListOutput::getUserId)
            .collect(Collectors.toList());
        
        Map<Long, UserEntity> longUserEntityMap = userService.mapByIds(userIds);
        
        // 获取订单ID列表
        List<Long> orderIds = outputs.stream()
            .map(OrderGroupListOutput::getOrderId)
            .collect(Collectors.toList());
        
        
        Map<Long, OrderEntity> orderEntityMap = orderService.mapByIds(orderIds);
        
        
        outputs.forEach(o -> {
            o.setUsername(longUserEntityMap.getOrDefault(o.getUserId(), new UserEntity()).getNickname());
            o.setCellphone(longUserEntityMap.getOrDefault(o.getUserId(), new UserEntity()).getCellphone());
            o.setTickets(ticketDetailsByOrderTicketIds.getOrDefault(o.getId(), new ArrayList<>()));
            
            OrderEntity orDefault = orderEntityMap.getOrDefault(o.getOrderId(), new OrderEntity());
            o.setRefundRemark(orDefault.getRefundRemark());
            
        });
        

        
        OrderDataModel orderDataModel = new OrderDataModel();
        
        List<OrderGroupPurchaseEntity> list = service.list(input);
        
        List<Long> orderIdList = list.stream().map(OrderGroupPurchaseEntity::getOrderId).collect(Collectors.toList());
        OrderEntity order = orderService.dateCount(OrderType.GROUP_PURCHASE_TICKET.getValue(), null, orderIdList);
        
        if (Objects.nonNull(order)){
            orderDataModel.setSumPayPrice(order.getSumPayPrice());
            orderDataModel.setWxSumPayPrice(order.getWxSumPayPrice());
            orderDataModel.setMemberSumPayPrice(order.getMemberSumPayPrice());
            orderDataModel.setCount(order.getTotalRecords());
            orderDataModel.setTicketCount(summarizeTicketCount(list, null));
            orderDataModel.setTicketAmount(summarizeTicketPrice(list, null));
        }
        
        
        OrderEntity refundOrder = orderService.dateCount(OrderType.GROUP_PURCHASE_TICKET.getValue(), OrderPayStatus.REFUND_SUCCESS.getValue(), orderIdList);
        
        if (Objects.nonNull(refundOrder)){
            orderDataModel.setRefundAmount(refundOrder.getSumPayPrice());
            orderDataModel.setRefundCount(refundOrder.getTotalRecords());
            orderDataModel.setRefundWxAmount(refundOrder.getWxSumPayPrice());
            orderDataModel.setRefundMemberAmount(refundOrder.getMemberSumPayPrice());
            orderDataModel.setRefundTicketCount(summarizeTicketCount(list, OrderTicketStatus.REFUND_SUCCESS));
        }
        
        orderDataModel.setTotal(page.getTotal());
        orderDataModel.setList(outputs);
        return orderDataModel;
    }
    
    @Override
    public void refund(TicketRefundInput input) {
        // 校验订单ID
        validateOrderId(input.getOrderId());
        
        OrderEntity order = orderService.getById(input.getOrderId());
        
        // 混合订单
        if (order.getOrderMixedId() != 0){
            List<OrderEntity> orderEntities = orderService.listByInMixedId(order.getOrderMixedId());
            orderEntities.forEach(it -> {
                it.setRefundRemark(input.getRemark());
                if (it.getType() == OrderType.TICKET){
                    orderGroupManager.refund(it, OrderGroupManager.RefundType.TICKET_AND_REFUND, input.getRefundCoupon());
                } else {
                    orderCommodityManager.refund(it, input.getRefundCoupon());
                }
            });
            
            OrderMixedEntity orderMixed = orderManager.updateOrderMixedStatus(order.getOrderMixedId());
            
            // 如果是微信支付
            if (order.getPayType() == OrderPayType.WXA){
                orderManager.refundToWeChat(order, orderMixed);
            }
            // 单独订单
        } else {
            order.setRefundRemark(input.getRemark());
            orderGroupManager.refund(order, OrderGroupManager.RefundType.TICKET_AND_REFUND, input.getRefundCoupon());
            
            // 如果是微信支付
            if (order.getPayType() == OrderPayType.WXA){
                orderManager.refundToWeChat(order, null);
            }
        }
    }
    
    private void validateOrderId(Long id) {
        if (orderService.isEmpty(id)) {
            throw new BadRequestException(
                ErrorCode.RECORD_NOT_EXIST,
                ErrorCode.RECORD_NOT_EXIST.getReasonPhrase()
            );
        }
    }
    
    /**
     * 根据给定的订单ID列表，汇总退票数量。
     *
     * @param list          包含影票订单的列表
     * @return 汇总的退票数量
     */
    public Integer summarizeTicketCount(List<OrderGroupPurchaseEntity> list, OrderTicketStatus status) {
        // 使用流过滤出orderId在refundOrderIds列表中的OrderTicketEntity对象
        List<OrderGroupPurchaseEntity> refundTickets = list.stream()
            .filter(ticket -> isRefundStatus(ticket, status))
            .collect(Collectors.toList());
        
        // 汇总退票数量
        Integer totalRefundedTickets = refundTickets.stream()
            .mapToInt(OrderGroupPurchaseEntity::getTicketCount)
            .sum();
        
        return totalRefundedTickets;
    }
    
    
    /**
     * 根据给定的订单ID列表，汇总退票金额。
     *
     * @param list          包含影票订单的列表
     * @param status        退票状态，如果为null，则汇总所有订单的退票数量
     * @return 汇总的退票数量
     */
    public BigDecimal summarizeTicketPrice(List<OrderGroupPurchaseEntity> list, OrderTicketStatus status) {
        // 使用流过滤出符合条件的OrderTicketEntity对象
        List<OrderGroupPurchaseEntity> refundTickets = list.stream()
            .filter(ticket -> isRefundStatus(ticket, status))
            .collect(Collectors.toList());
        
        // 汇总退票金额
        BigDecimal totalRefundedAmount = refundTickets.stream()
            .map(OrderGroupPurchaseEntity::getTicketPrice) // 假设getTicketPrice返回的是BigDecimal类型
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        
        return totalRefundedAmount;
    }
    
    private boolean isRefundStatus(OrderGroupPurchaseEntity ticket, OrderTicketStatus status) {
        return status == null || ticket.getTicketStatus() == status;
    }
}
